home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 23 code / QuickTime Music / QTMADevelop95.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-12  |  17.3 KB  |  753 lines  |  [TEXT/KAHL]

  1.      
  2. /*--------------------------
  3.     Inclusions
  4. --------------------------*/
  5.  
  6. #include <QuickDraw.h>
  7. #include <Windows.h>
  8. #include <StandardFile.h>
  9. #include <OSUtils.h>
  10. #include <Script.h>
  11.  
  12. #include "BigEasy2.h"
  13.  
  14. // Note that at the time of publication, the QuickTime Music
  15. // headers were still in flux, hence this "temp" file
  16. #include "Music 2.1 Temp.h"
  17.  
  18. /*--------------------------
  19.     Limits and Konstants
  20. --------------------------*/
  21. enum
  22.     {
  23.     mOpen = 100,
  24.     mClose
  25.     };
  26.  
  27. typedef struct
  28.     {
  29.     WindowPtr w;
  30.     } Globals;
  31.  
  32. static Globals g;
  33.  
  34.  
  35. /*--------------------------
  36.     Prototypes
  37. --------------------------*/
  38. static void GoAwayDoc(short n);
  39. static void LetsQuit(short n,short menuItem,short menuRef);
  40. static void OpenWindow(short n,short menuItem,short menuRef);
  41. static void InitVars(void);
  42.  
  43. static void SDrawDoc(short n);
  44. static void SClickDoc(short n,Point p,short mods);
  45. static void SKeyDoc(short n,short key,short code,short mods);
  46. static void SIdleDoc(short n, Boolean front);
  47.  
  48. void ActivateDoc(short n);
  49. void DeactivateDoc(short n);
  50.  
  51.  
  52. /*--------------------------
  53.     Computer Programs
  54. --------------------------*/
  55.  
  56.  
  57.  
  58.  
  59. void PlaySomeNotes(short a,short b,short c);
  60. void PickThenPlaySomeNotes(short xx1,short xx2,short xx3);
  61. void PlaySomeBentNotes(short xx1,short xx2,short xx3);
  62. unsigned long *BuildTuneHeader(long *longCount);
  63. Handle BuildTuneSequence(long *duration);
  64. void BuildSequenceAndPlay(short xx1,short xx2,short xx3);
  65. void BuildMusicMovie(short xx1,short xx2,short xx3);
  66. void UseMIDIInput(short xx1,short xx2,short xx3);
  67.  
  68.  
  69. void PlaySomeNotes(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */
  70.     {
  71.     NoteAllocator na;
  72.     NoteChannel nc;
  73.     NoteRequest nr;
  74.     ComponentResult thisError;
  75.     long t,i;
  76.  
  77.     na = 0;
  78.     nc = 0;
  79.  
  80.     /*
  81.      * Open up the Note Allocator
  82.      */
  83.     na = OpenDefaultComponent('nota',0);
  84.     if(!na)
  85.         goto goHome;
  86.  
  87.     /*
  88.      * Fill out a Note Request using NAStuffToneDescription
  89.      * to help, and allocate a Note Channel
  90.      */
  91.     nr.info.flags = 0;            /* post qt 2.0 only */
  92.     nr.info.reserved = 0;        /* post qt 2.0 only */
  93.     nr.info.polyphony = 2;        /* simultaneous tones */
  94.     nr.info.typicalPolyphony = 0x00010000;
  95.     thisError = NAStuffToneDescription(na,1,&nr.tone);    /* 1 is Piano */
  96.  
  97.     thisError = NANewNoteChannel(na,&nr,&nc);
  98.     if(thisError || !nc)
  99.         goto goHome;
  100.  
  101.     /*
  102.      * If we've gotten this far, then things are ok
  103.      * to play some musical notes. Lovely.
  104.      */
  105.     NAPlayNote(na,nc,60,80);    /* middle C at velocity 80 */
  106.     Delay(40,&t);            /* delay 2/3 of a second */
  107.     NAPlayNote(na,nc,60,0);    /* middle C at velocity 0: end note */
  108.     Delay(40,&t);            /* delay 2/3 of a second */
  109.  
  110.     /*
  111.      * Obligatory do-loop of rising tones
  112.      */
  113.     for(i = 60; i <= 84; i++)
  114.         {
  115.         NAPlayNote(na,nc,i,80);    /* pitch i at velocity 80 */
  116.         NAPlayNote(na,nc,i+7,80);    /* pitch i+7 (musical fifth) at velocity 80 */
  117.         Delay(10,&t);            /* delay 1/6 of a second */
  118.         NAPlayNote(na,nc,i,0);    /* pitch i at velocity 0: end note */
  119.         NAPlayNote(na,nc,i+7,0);    /* pitch i+7 at velocity 0: end note */
  120.         }
  121. goHome:
  122.     if(nc)
  123.         NADisposeNoteChannel(na,nc);
  124.     if(na)
  125.         CloseComponent(na);
  126.     }
  127.  
  128. void PlayShepardMelody(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */;
  129. void PlayShepardMelody(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */
  130.     {
  131.     NoteAllocator na;
  132.     NoteChannel nc;
  133.     NoteRequest nr;
  134.     ComponentResult thisError;
  135.     unsigned long i,j,v;
  136.     long t;
  137.  
  138.     na = 0;
  139.     nc = 0;
  140.  
  141.     /*
  142.      * Open up the Note Allocator
  143.      */
  144.     na = OpenDefaultComponent('nota',0);
  145.     if(!na)
  146.         goto goHome;
  147.  
  148.     /*
  149.      * Fill out a Note Request using NAStuffToneDescription
  150.      * to help, and allocate a Note Channel
  151.      */
  152.     nr.info.flags = 0;            /* post qt 2.0 only */
  153.     nr.info.reserved = 0;        /* post qt 2.0 only */
  154.     nr.info.polyphony = 3;        /* simultaneous tones */
  155.     nr.info.typicalPolyphony = 0x00010000;
  156.     thisError = NAStuffToneDescription(na,1,&nr.tone);    /* 1 is Piano */
  157.  
  158.     thisError = NANewNoteChannel(na,&nr,&nc);
  159.     if(thisError || !nc)
  160.         goto goHome;
  161.  
  162.     /*
  163.      * play Roger Shepard's melody
  164.      */
  165.     i = 0;
  166.     while(!Button())
  167.         {
  168.         for(j = i % 13; j < 128; j+=13)
  169.             {
  170.             v = j<64 ? j * 2 : (127 - j) * 2;
  171.             NAPlayNote(na,nc,j,v);
  172.             }
  173.         Delay(13,&t);
  174.         for(j = i % 13; j < 128; j+=13)
  175.             NAPlayNote(na,nc,j,0);
  176.         i++;
  177.         }
  178. goHome:
  179.     if(nc)
  180.         NADisposeNoteChannel(na,nc);
  181.     if(na)
  182.         CloseComponent(na);
  183.     }
  184.  
  185.  
  186.  
  187. void PickThenPlaySomeNotes(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */
  188.     {
  189.     NoteAllocator na;
  190.     NoteChannel nc;
  191.     NoteRequest nr;
  192.     ComponentResult thisError;
  193.     long t,i;
  194.  
  195.     na = 0;
  196.     nc = 0;
  197.  
  198.     /*
  199.      * Open up the Note Allocator
  200.      */
  201.     na = OpenDefaultComponent('nota',0);
  202.     if(!na)
  203.         goto goHome;
  204.  
  205.     /*
  206.      * Fill out a Note Request using NAStuffToneDescription
  207.      * to help, and allocate a Note Channel
  208.      */
  209.     nr.info.flags = 0;            /* post qt 2.0 only */
  210.     nr.info.reserved = 0;        /* post qt 2.0 only */
  211.     nr.info.polyphony = 2;        /* simultaneous tones */
  212.     nr.info.typicalPolyphony = 0x00010000;
  213.     thisError = NAStuffToneDescription(na,1,&nr.tone);    /* 1 is Piano */
  214.  
  215.     thisError = NAPickInstrument(na,nil,"\pPick An Instrument:",&nr.tone, 0,0,0,0);
  216.     if(thisError)
  217.         goto goHome;
  218.  
  219.     thisError = NANewNoteChannel(na,&nr,&nc);
  220.     if(thisError || !nc)
  221.         goto goHome;
  222.  
  223.     /*
  224.      * If we've gotten this far, then things are ok
  225.      * to play some musical notes. Lovely.
  226.      */
  227.     NAPlayNote(na,nc,60,80);    /* middle C at velocity 80 */
  228.     Delay(40,&t);            /* delay 2/3 of a second */
  229.     NAPlayNote(na,nc,60,0);    /* middle C at velocity 0: end note */
  230.     Delay(40,&t);            /* delay 2/3 of a second */
  231.  
  232.     /*
  233.      * Obligatory do-loop of rising tones
  234.      */
  235.     for(i = 60; i <= 84; i++)
  236.         {
  237.         NAPlayNote(na,nc,i,80);    /* pitch i at velocity 80 */
  238.         NAPlayNote(na,nc,i+7,80);    /* pitch i+7 (musical fifth) at velocity 80 */
  239.         Delay(10,&t);            /* delay 1/6 of a second */
  240.         NAPlayNote(na,nc,i,0);    /* pitch i at velocity 0: end note */
  241.         NAPlayNote(na,nc,i+7,0);    /* pitch i+7 at velocity 0: end note */
  242.         }
  243. goHome:
  244.     if(nc)
  245.         NADisposeNoteChannel(na,nc);
  246.     if(na)
  247.         CloseComponent(na);
  248.     }
  249.  
  250.  
  251.  
  252. void PlaySomeBentNotes(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */
  253.     {
  254.     NoteAllocator na;
  255.     NoteChannel nc;
  256.     NoteRequest nr;
  257.     ComponentResult thisError;
  258.     long t,i;
  259.  
  260.     na = 0;
  261.     nc = 0;
  262.  
  263.     /*
  264.      * Open up the Note Allocator
  265.      */
  266.     na = OpenDefaultComponent('nota',0);
  267.     if(!na)
  268.         goto goHome;
  269.  
  270.     /*
  271.      * Fill out a Note Request using NAStuffToneDescription
  272.      * to help, and allocate a Note Channel
  273.      */
  274.     nr.info.flags = 0;            /* post qt 2.0 only */
  275.     nr.info.reserved = 0;        /* post qt 2.0 only */
  276.     nr.info.polyphony = 2;        /* simultaneous tones */
  277.     nr.info.typicalPolyphony = 0x00010000;
  278.     thisError = NAStuffToneDescription(na,17,&nr.tone);    /* 17 is an organ tone */
  279.  
  280.     thisError = NANewNoteChannel(na,&nr,&nc);
  281.     if(thisError || !nc)
  282.         goto goHome;
  283.  
  284.     Delay(30,&t);
  285.  
  286.     /*
  287.      * If we've gotten this far, then things are ok
  288.      * to play some musical notes. Lovely.
  289.      */
  290.     NAPlayNote(na,nc,60,80);    /* middle C at velocity 80 */
  291.     NAPlayNote(na,nc,67,60);    /* g at velocity 60 */
  292.     Delay(30,&t);
  293.  
  294.     /*
  295.      * Loop through differing pitch bendings
  296.      */
  297.     for(i = 0; i <= 768; i+= 10)        /* bend 3 semitones */
  298.         {
  299.         NASetController(na,nc,kControllerPitchBend,i);
  300.         Delay(1,&t);
  301.         }
  302.     Delay(30,&t);
  303.     for(i = 768; i >= 0; i-= 10)        /* bend back to normal*/
  304.         {
  305.         NASetController(na,nc,kControllerPitchBend,i);
  306.         Delay(1,&t);
  307.         }
  308.     Delay(30,&t);
  309.  
  310.     NAPlayNote(na,nc,60,0);    /* middle C off */
  311.     NAPlayNote(na,nc,67,0);    /* G off */
  312.  
  313. goHome:
  314.     if(nc)
  315.         NADisposeNoteChannel(na,nc);
  316.     if(na)
  317.         CloseComponent(na);
  318.     }
  319.  
  320.  
  321. #define kNoteRequestHeaderEventLength (sizeof(NoteRequest)/sizeof(long) + 2) /* longwords */
  322. unsigned long *BuildTuneHeader(long *longCount)
  323.     {
  324.     unsigned long *header;
  325.     unsigned long *w,*w2;
  326.     NoteRequest *nr;
  327.     NoteAllocator na;    /* just for the NAStuffToneDescription call */
  328.     ComponentResult thisError;
  329.  
  330.     header = 0;
  331.     na = 0;
  332.  
  333.     /*
  334.      * Open up the Note Allocator
  335.      */
  336.     na = OpenDefaultComponent('nota',0);
  337.     if(!na)
  338.         goto goHome;
  339.  
  340.     /*
  341.      * Allocate space for the tune header,
  342.      * rather inflexibly.
  343.      */
  344.     header = (unsigned long *)
  345.             NewPtrClear((2 * kNoteRequestHeaderEventLength + 1) * sizeof(long));
  346.     if(!header)
  347.         goto goHome;
  348.  
  349.     w = header;
  350.  
  351.     /*
  352.      * Stuff request for piano polyphony 4
  353.      */
  354.     w2 = w + kNoteRequestHeaderEventLength - 1; /* last longword of general event */
  355.     _StuffGeneralEvent(*w,*w2, 1, kGeneralEventNoteRequest, kNoteRequestHeaderEventLength);
  356.     nr = (NoteRequest *)(w + 1);
  357.     nr->info.flags = 0;            /* post qt 2.0 only */
  358.     nr->info.reserved = 0;        /* post qt 2.0 only */
  359.     nr->info.polyphony = 4;        /* simultaneous tones */
  360.     nr->info.typicalPolyphony = 0x00010000;
  361.     thisError = NAStuffToneDescription(na,1,&nr->tone);    /* 1 is Piano */
  362.     w += kNoteRequestHeaderEventLength;
  363.  
  364.     /*
  365.      * Stuff request for violin polyphony 3
  366.      */
  367.     w2 = w + kNoteRequestHeaderEventLength - 1; /* last longword of general event */
  368.     _StuffGeneralEvent(*w,*w2, 2, kGeneralEventNoteRequest, kNoteRequestHeaderEventLength);
  369.     nr = (NoteRequest *)(w + 1);
  370.     nr->info.flags = 0;            /* post qt 2.0 only */
  371.     nr->info.reserved = 0;        /* post qt 2.0 only */
  372.     nr->info.polyphony = 3;        /* simultaneous tones */
  373.     nr->info.typicalPolyphony = 0x00010000;
  374.     thisError = NAStuffToneDescription(na,41,&nr->tone);    /* ???!!! what is violin? */
  375.     w += kNoteRequestHeaderEventLength;
  376.  
  377.     *w++ = 0x60000000;        /* end of sequence marker */
  378.  
  379.  
  380. goHome:
  381.     if(na)
  382.         CloseComponent(na);
  383.  
  384.     if(longCount)
  385.         *longCount = 2 * kNoteRequestHeaderEventLength;
  386.  
  387.     return header;
  388.     }
  389.  
  390. Handle BuildTuneSequence(long *duration)
  391.     {
  392.     unsigned long *sequence;
  393.     unsigned long *w;
  394.     Handle h;
  395.  
  396.     /*
  397.      * Allocate space for the tune sequence,
  398.      * rather inflexibly.
  399.      */
  400. #define kNoteDuration 240 /* in 600ths of a second */
  401. #define kRestDuration 300 /* in 600ths - tempo will be 120bpm */
  402.  
  403.     h = NewHandleClear(22 * sizeof(long));
  404.     if(!h)
  405.         goto goHome;
  406.     HLock(h);
  407.     sequence = (unsigned long *) *h;
  408.  
  409.     w = sequence;
  410.  
  411.     _StuffNoteEvent(*w++,1,60,100,kNoteDuration);    /* piano C */
  412.     _StuffRestEvent(*w++,kRestDuration);
  413.     _StuffNoteEvent(*w++,2,60,100,kNoteDuration);    /* violin C */
  414.     _StuffRestEvent(*w++,kRestDuration);
  415.  
  416.     _StuffNoteEvent(*w++,1,63,100,kNoteDuration);    /* piano */
  417.     _StuffRestEvent(*w++,kRestDuration);
  418.     _StuffNoteEvent(*w++,2,64,100,kNoteDuration);    /* violin */
  419.     _StuffRestEvent(*w++,kRestDuration);
  420.  
  421.     /*
  422.      * make the 5th and 6th notes much softer, just for fun
  423.      */
  424.     _StuffNoteEvent(*w++,1,67,60,kNoteDuration);    /* piano */
  425.     _StuffRestEvent(*w++,kRestDuration);
  426.     _StuffNoteEvent(*w++,2,66,60,kNoteDuration);    /* violin */
  427.     _StuffRestEvent(*w++,kRestDuration);
  428.  
  429.     _StuffNoteEvent(*w++,1,72,100,kNoteDuration);    /* piano */
  430.     _StuffRestEvent(*w++,kRestDuration);
  431.     _StuffNoteEvent(*w++,2,73,100,kNoteDuration);    /* violin */
  432.     _StuffRestEvent(*w++,kRestDuration);
  433.  
  434.     _StuffNoteEvent(*w++,1,60,100,kNoteDuration);    /* piano */
  435.     _StuffNoteEvent(*w++,1,67,100,kNoteDuration);    /* piano */
  436.     _StuffNoteEvent(*w++,2,63,100,kNoteDuration);    /* violin */
  437.     _StuffNoteEvent(*w++,2,72,100,kNoteDuration);    /* violin */
  438.     _StuffRestEvent(*w++,kRestDuration);
  439.  
  440.     *w++ = 0x60000000;    /* end marker */
  441.  
  442. goHome:
  443.     if(duration)
  444.         *duration = 9 * kRestDuration;
  445.     return h;
  446.     }
  447.  
  448.  
  449. void BuildSequenceAndPlay(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */
  450.     {
  451.     Handle sequenceH;
  452.     unsigned long *header;
  453.     unsigned long *sequence;
  454.     TunePlayer tp;
  455.     TuneStatus ts;
  456.     ComponentResult thisError;
  457.  
  458.     tp = 0;
  459.  
  460.     header = BuildTuneHeader(nil);
  461.     sequenceH = BuildTuneSequence(nil);
  462.  
  463.     if(!sequenceH || !header)
  464.         goto goHome;
  465.  
  466.     sequence = (unsigned long *)*sequenceH;
  467.  
  468.     tp = OpenDefaultComponent(kTunePlayerType,0);
  469.     if(!tp)
  470.         goto goHome;
  471.  
  472.     thisError = TuneSetHeader(tp,header);
  473.  
  474.         {
  475.         long t;
  476.         Delay(10,&t);
  477.         }
  478.  
  479.     thisError = TuneQueue(tp,sequence,0x00010000,0,0x7FFFFFFF,0,0,0);
  480.  
  481.     /*
  482.      * wait until the sequence finishes playing,
  483.      * or the user clicks the mouse.
  484.      */
  485. spin:
  486.     thisError = TuneGetStatus(tp,&ts);
  487.     if(ts.queueTime && !Button())
  488.         goto spin;    /* I like to use gotos primarily to shock the children. */
  489.  
  490. goHome:
  491.     if(tp)
  492.         CloseComponent(tp);
  493.     if(header)
  494.         DisposePtr((Ptr)header);
  495.     if(sequenceH)
  496.         DisposeHandle(sequenceH);
  497.     }
  498.  
  499.  
  500. typedef struct
  501.     {
  502.     NoteAllocator na;
  503.     NoteChannel nc;
  504.     } MIDIInputExample;
  505.  
  506. pascal ComponentResult AReadHook(MusicMIDIPacket *mp, long refCon);
  507. pascal ComponentResult AReadHook(MusicMIDIPacket *mp, long refCon)
  508.     {
  509.     MIDIInputExample *mie;
  510.     Boolean major;
  511.     short status,pitch,vel;
  512.  
  513.     mie = (MIDIInputExample *)refCon;
  514.  
  515.     if(mp->reserved == kMusicPacketPortLost)        /* port gone? make channel quiet */
  516.         NASetNoteChannelVolume(mie->na,mie->nc,0);
  517.     else if(mp->reserved == kMusicPacketPortFound)    /* port back? raise volume */
  518.         NASetNoteChannelVolume(mie->na,mie->nc,0x00010000);
  519.     else if(mp->length == 3)
  520.         {
  521.         status = mp->data[0] & 0xF0;
  522.         pitch = mp->data[1];
  523.         vel = mp->data[2];
  524.         switch(status)
  525.             {
  526.             case 0x80:
  527.                 vel = 0;
  528.     /* falls into case 0x90. Almost as fun as a goto, hmm, mom? */
  529.             case 0x90:
  530.                 major = pitch % 5 == 0;
  531.                 NAPlayNote(mie->na,mie->nc,pitch,vel);
  532.                 NAPlayNote(mie->na,mie->nc,pitch+3+major,vel);
  533.                 NAPlayNote(mie->na,mie->nc,pitch+7,vel);
  534.                 break;
  535.             }
  536.         }
  537.     return noErr;
  538.     }
  539.  
  540.  
  541. void UseMIDIInput(short xx1,short xx2,short xx3)
  542.     {
  543.     ComponentResult result;
  544.     MIDIInputExample mie;
  545.     NoteRequest nr;
  546.     MusicMIDIReadHookUPP readHookUPP = nil;
  547.  
  548.     mie.na = OpenDefaultComponent('nota',0);
  549.     if(!mie.na)
  550.         goto goHome;
  551.  
  552.     nr.info.flags = 0;            /* post qt 2.0 only */
  553.     nr.info.reserved = 0;        /* post qt 2.0 only */
  554.     nr.info.polyphony = 2;
  555.     nr.info.typicalPolyphony = 0x00010000;
  556.     result = NAStuffToneDescription(mie.na,1,&nr.tone);        /* piano */
  557.     result = NANewNoteChannel(mie.na,&nr,&mie.nc);
  558.     
  559.     readHookUPP = NewMusicMIDIReadHookProc(AReadHook);
  560.     result = NAUseDefaultMIDIInput(mie.na,readHookUPP,(long)&mie,0);
  561.     while(!Button());
  562.     result = NALoseDefaultMIDIInput(mie.na);
  563.  
  564. goHome:
  565.     if(readHookUPP)
  566.         DisposeRoutineDescriptor(readHookUPP);
  567.     if(mie.na)
  568.         CloseComponent(mie.na);        /* disposes notechannel too */
  569.     }
  570.  
  571.  
  572.  
  573.  
  574. void BuildMusicMovie(short xx1,short xx2,short xx3)    /* dummy arguments for big easy shell */
  575.     {
  576.     ComponentResult result;
  577.     StandardFileReply reply;
  578.     short resRefNum;
  579.     Movie mo;
  580.     Track tr;
  581.     Media me;
  582.     MusicDescription *md,**mdH;
  583.     long duration,headerLength;
  584.     unsigned long *w,*header;
  585.     Handle tuneH;
  586.  
  587.     // • prompt user for new file name
  588.  
  589.     StandardPutFile ("\pMusic movie file name:", "\pMovie File", &reply );
  590.     if(!reply.sfGood)
  591.         goto goHome;
  592.  
  593.     // • create the movie, and track, and media
  594.  
  595.     result = CreateMovieFile(&reply.sfFile,'TVOD',smCurrentScript,createMovieFileDeleteCurFile,&resRefNum,&mo);
  596.     tr = NewMovieTrack(mo,0,0,256);
  597.     me = NewTrackMedia(tr,MusicMediaType, 600, nil, 0 );
  598.  
  599.     // • create a music sample description
  600.  
  601.     header = BuildTuneHeader(&headerLength);
  602.  
  603.     mdH = (MusicDescription **)NewHandleClear(sizeof(MusicDescription) - 4
  604.             + headerLength*sizeof(long)
  605.             + 4);                                                    /* end marker */
  606.     if(!mdH)
  607.         goto goHome;
  608.  
  609.     md = *mdH;
  610.     md->descSize = GetHandleSize((Handle)mdH);
  611.     md->dataFormat = 'musi';
  612.     w = md->headerData;
  613.     BlockMove(header,w,headerLength * sizeof(long));
  614.     w += headerLength;
  615.     *w = 0x60000000;
  616.  
  617.     DisposePtr((Ptr)header);
  618.  
  619.     // • Get a tune, and add it to the media, then finish up.
  620.  
  621.     tuneH = BuildTuneSequence(&duration);
  622.  
  623.     result = BeginMediaEdits(me);
  624.  
  625.     result = AddMediaSample(me,tuneH,0,
  626.             GetHandleSize(tuneH),
  627.             duration,(SampleDescriptionHandle)mdH,
  628.             1,0,nil);
  629.  
  630.     result = EndMediaEdits(me);
  631.     result = InsertMediaIntoTrack(tr,0,0,duration,(1L<<16));
  632.  
  633.     result = OpenMovieFile(&reply.sfFile, &resRefNum,
  634.             fsRdWrPerm);
  635.     result = AddMovieResource( mo,resRefNum, 0, 0);
  636.     result = CloseMovieFile(resRefNum);
  637.  
  638.     DisposeMovie(mo);
  639. goHome:;
  640.     }
  641.  
  642.  
  643. void GoAwayDoc(short n)
  644. /*
  645.  * Close that window...
  646.  */
  647.     {
  648.     UninstallWindow(n);
  649.     }
  650.  
  651. void ActivateDoc(short n)
  652.     {
  653. #pragma unused (n)
  654.      SetMenuItem(mClose,1,0,0,nil);                /* enable "Close" menu item        */
  655.     SetMenuItem(mOpen,-1,0,0,nil);                /* disable "Open" menu item        */
  656.     }
  657.  
  658. void DeactivateDoc(short n)
  659.     {
  660. #pragma unused (n)
  661.     SetMenuItem(mClose,-1,0,0,nil);                /* disable "Close" menu item    */
  662.     SetMenuItem(mOpen,1,0,0,nil);                /* enable "Open" menu item        */
  663.     }
  664.  
  665. void LetsQuit(short n,short menuItem,short menuRef)
  666.     {
  667. #pragma unused (n,menuItem,menuRef)
  668.     gQuitApp++;
  669.     }
  670.  
  671. #define kWindowWidth 200
  672. #define kWindowHeight 100
  673.  
  674. void OpenWindow(short n,short menuItem,short menuRef)
  675.     {
  676. #pragma unused (n,menuItem,menuRef)
  677.     Rect r;
  678.  
  679.     SetRect(&r,0,0,kWindowWidth,kWindowHeight);
  680.     OffsetRect(&r,20,40);
  681.  
  682.     g.w = InstallWindow(1,"\p",&r,0,wCopyDraw,
  683.                                 SDrawDoc,SClickDoc,SKeyDoc,nil,
  684.                                 ActivateDoc,DeactivateDoc,SIdleDoc);
  685.     }
  686.  
  687. static void SDrawDoc(short n)
  688.     {
  689.     EraseRect(&gBigRect);
  690.     MoveTo(10,50);
  691.     DrawString("\pExamples of QuickTime Music Architecture");
  692.     MoveTo(10,65);
  693.     DrawString("\pDavid Van Brink, 1995");
  694.     MoveTo(10,80);
  695.     DrawString("\p©Apple Computer");
  696.     }
  697.  
  698. static void SClickDoc(short n,Point p,short mods)
  699.     {
  700.     }
  701.  
  702. static void SKeyDoc(short n,short key,short code,short mods)
  703.     {
  704.     }
  705.  
  706. static void SIdleDoc(short n, Boolean front)
  707.     {
  708.     }
  709.  
  710.  
  711.  
  712.  
  713.  
  714. void InitVars()
  715. /*
  716.  * Called once at startup: yes, it
  717.  * inits the vars.
  718.  */
  719.     {
  720.     EnterMovies();
  721.     }
  722.  
  723.  
  724.  
  725. void Bootstrap()
  726.     {
  727.     InitVars();
  728.  
  729. /*** File Menu ***/
  730.     InstallMenu("\pFile",nil,0);
  731.     InstallMenuItem("\pQuit/Q",LetsQuit,0);
  732.     InstallMenuItem("\p(-",nil,0);
  733.     InstallMenuItem("\pPlay Some Notes/1",PlaySomeNotes,0);
  734.     InstallMenuItem("\pPlay Shepard Melody/¡",PlayShepardMelody,0);
  735.     InstallMenuItem("\pPick Then Play Some Notes/2",PickThenPlaySomeNotes,0);
  736.     InstallMenuItem("\pPlay Some Bent Notes/3",PlaySomeBentNotes,0);
  737.     InstallMenuItem("\pBuild And Play Sequence/4",BuildSequenceAndPlay,0);
  738.     InstallMenuItem("\pBuild Music Movie/5",BuildMusicMovie,0);
  739.     InstallMenuItem("\pUse MIDI Input/6",UseMIDIInput,0);
  740. /*** Edit Menu ***/
  741.     InstallEditMenu(nil,nil,nil,nil,nil);
  742.  
  743.     OpenWindow(0,0,0);
  744.     }
  745.  
  746. void Hatstrap()
  747. /*
  748.   * clean up
  749.   */
  750.     {
  751.     }
  752.  
  753.